﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.Web.Mvc;
using AuthorizationServer.Models;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity;

namespace AuthorizationServer.Controllers
{
    [Authorize(Roles="Admin")]
    public class UserController : Controller
    {
        private IdentityDbContext db = new IdentityDbContext();

        // GET: /User/
        public async Task<ActionResult> Index()
        {
            return View(await db.Users.ToListAsync());
        }

        public ActionResult IndexRoles(string userId)
        {
            UserManager<IdentityUser> um = new UserManager<IdentityUser>(new UserStore<IdentityUser>());
            var userRoles = um.GetRoles(userId);

            List<IdentityUserRole> userRoleList = new List<IdentityUserRole>();
            foreach (IdentityRole role in db.Roles.Where(x => !userRoles.Any(y => x.Name == y)))
            {
                IdentityUserRole userRole = new IdentityUserRole();
                userRole.Role = role;
                userRole.UserId = userId;
                userRoleList.Add(userRole);
            }
            return PartialView(userRoleList);
        }

        public ActionResult AddRole(string userId, string roleName)
        {
            UserManager<IdentityUser> um = new UserManager<IdentityUser>(new UserStore<IdentityUser>());
            um.AddToRole(userId,roleName);

            return RedirectToAction("Details", new { id = userId });
        }

        public ActionResult RemoveRole(string userId, string roleName)
        {
            UserManager<IdentityUser> um = new UserManager<IdentityUser>(new UserStore<IdentityUser>());
            um.RemoveFromRole(userId, roleName);

            return RedirectToAction("Details", new { id = userId });
        }
        
        // GET: /User/Details/5
        public async Task<ActionResult> Details(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            IdentityUser myidentityuser = db.Users.Find(id);
            if (myidentityuser == null)
            {
                return HttpNotFound();
            }
            return View(myidentityuser);
        }

        // GET: /User/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: /User/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Create([Bind(Include = "UserName,Password,ConfirmPassword")] RegisterBindingModel myidentityuser)
        {
            if (ModelState.IsValid )
            {
                UserManager<IdentityUser> um = new UserManager<IdentityUser>(new UserStore<IdentityUser>());

                IdentityUser user = new IdentityUser
                {
                    UserName = myidentityuser.UserName
                };
                IdentityResult result = await um.CreateAsync(user, myidentityuser.Password);

                return RedirectToAction("Index");
            }

            return View(myidentityuser);
        }

        // GET: /User/Edit/5
        public async Task<ActionResult> Edit(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            IdentityUser myidentityuser = db.Users.Find(id);
            if (myidentityuser == null)
            {
                return HttpNotFound();
            }

            ChangePasswordBindingModel user = new ChangePasswordBindingModel();
            user.Id = myidentityuser.Id;
            user.UserName = myidentityuser.UserName;

            return View(user);
        }

        // POST: /User/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit([Bind(Include = "Id,UserName,OldPassword,NewPassword,ConfirmPassword")] ChangePasswordBindingModel myidentityuser)
        {
            if (ModelState.IsValid)
            {
                UserManager<IdentityUser> um = new UserManager<IdentityUser>(new UserStore<IdentityUser>());

                IdentityResult result = await um.ChangePasswordAsync(myidentityuser.Id, myidentityuser.OldPassword,myidentityuser.NewPassword);
                return RedirectToAction("Index");
            }
            return View(myidentityuser);
        }

        // GET: /User/Delete/5
        public async Task<ActionResult> Delete(string id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            IdentityUser myidentityuser = db.Users.Find(id);
            if (myidentityuser == null)
            {
                return HttpNotFound();
            }
            return View(myidentityuser);
        }

        // POST: /User/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> DeleteConfirmed(string id)
        {
            IdentityUser myidentityuser = db.Users.Find(id);
            db.Users.Remove(myidentityuser);
            await db.SaveChangesAsync();
            return RedirectToAction("Index");
        }
        

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
